<template>
  <div class="chart-container">
    <ViewChart
      ref="myRef"
      :options="myOption"
    />
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, toRefs, watch, onMounted, defineAsyncComponent, PropType } from 'vue';
import { EChartsOption } from 'echarts'
import { CDataNode, CVariableDataItem, CGraphEntity, CDynamicDataItem } from 'stores/editorModels';
import { CChartPropertyItem } from 'components/views/chart/chartViewModel';
import { useMessageNotify } from 'src/hook/common/useMessageNotify';
const ViewChart = defineAsyncComponent(() => import('./ViewChart.vue'));
export default defineComponent({
  name: 'ViewChartCurve',
  components: {
    ViewChart
  },
  props: {
    detail: {
      type: Object,
      default: () => {
        return {} as CGraphEntity
      }
    },
    dynamicData: {
      type: Array as PropType<CVariableDataItem[]>,
      default: () => {
        return [] as CVariableDataItem[]
      }
    }
  },
  setup (props, context) {
    // 响应数据解构
    const {
      detail,
      dynamicData
    } = toRefs(props);

    //错误通知
    const {
      showMessage
    } = useMessageNotify();

    // chart dom,InstanceType获取子组件的类型
    let myRef = ref<InstanceType<typeof ViewChart> | null>(null);
    let param = ref<CChartPropertyItem>({
      title: '',
      xName: '',
      xType: '',
      yName: '',
      yType: '',
      xDataNum: 7
    });

    //x轴刻度显示
    let xScale = ref<string[]>(['周一', '周二', '周三', '周四', '周五', '周六', '周日']);

    //初始数据
    let xyData = ref<CDynamicDataItem[]>([]);

    //chart数据集
    let xyDataSet = ref<CDynamicDataItem[][]>([
      [
        { vid: 1, name: '', value: 20 },
        { vid: 1, name: '', value: 40 },
        { vid: 1, name: '', value: 90 },
        { vid: 1, name: '', value: 60 },
        { vid: 1, name: '', value: 10 },
        { vid: 1, name: '', value: 40 },
        { vid: 1, name: '', value: 60 }
      ]
    ]);

    //chart数据样式
    let myOption: EChartsOption = {
      title: {
        show: true,
        text: '',
        textStyle: {
          fontWeight: 'bolder',
          fontSize: 18
        }
      },
      tooltip: {
        show: true,
        trigger: 'item'
      },
      legend: {
        show: true,
        orient: 'horizontal', // 图例列表的布局朝向(horizontal或vertical)
        itemWidth: 18,
        itemHeight: 12,
        icon: 'roundRect',
        left: '120',
        tooltip: {  //  鼠标hover提示,图表配置了tooltip后才会生效
          show: true
        }
      },
      grid: {
        show: true,
        backgroundColor: 'transparent' //背景色
      },
      xAxis: {
        type: 'category', // x轴坐标轴类型
        name: '', // 坐标轴名称
        nameTextStyle: {
          fontSize: 14,
          fontWeight: 'bolder'
        }
      },
      yAxis: {
        type: 'value', // y轴坐标轴类型
        name: '',
        nameTextStyle: {
          fontSize: 14,
          fontWeight: 'bolder'
        }
      },
      series: []
    };

    //动态增加曲线
    const addToChart = (): void => {
      if (myOption.series) {
        //坐标系设置
        (myOption.title as any).text = param.value.title; //标题
        (myOption.xAxis as any).type = param.value.xType; // x轴坐标轴类型
        (myOption.xAxis as any).name = param.value.xName; // 坐标轴名称
        (myOption.xAxis as any).data = xScale.value; // 坐标轴刻度显示
        (myOption.yAxis as any).type = param.value.yType; // x轴坐标轴类型
        (myOption.yAxis as any).name = param.value.yName; // 坐标轴名称
        (myOption.series as any).length = 0; //series清空

        //曲线设置
        for (let i = 0; i < xyDataSet.value.length; i++) {
          let series_item = {
            data: xyDataSet.value[i], //对应的动态数据
            type: 'line', // 图表类型
            smooth: true
          };

          (myOption.series as any).push(series_item);
        }
      }
    };

    //属性更新
    const configProperty = () => {
      //个性化属性,计算长度，进行校验，一旦格式出错，涉及到数据错位，报错
      if ((detail.value?.propsItem) &&
        (detail.value?.propsItem.length > 0)) {
        //取出属性值
        let i = 0;
        let num;
        param.value.title = (detail.value.propsItem[i++].value);
        param.value.xName = (detail.value.propsItem[i++].value);
        param.value.xType = (detail.value.propsItem[i++].value);
        param.value.yName = (detail.value.propsItem[i++].value);
        param.value.yType = (detail.value.propsItem[i++].value);
        num = parseInt((detail.value.propsItem[i++].value));
        if (!isNaN(num)) {
          param.value.xDataNum = num;
        } else {
          showMessage('ChartCurve属性类型不正确！');
        }
      } else {
        showMessage('ChartCurve属性不正确！');
      }

      //生成数据节点
      if ((detail.value.dataItem) &&
        (detail.value?.dataItem.length > 0)) {
        xyData.value.length = 0;
        detail.value.dataItem.forEach((item: CDataNode) => {
          xyData.value.push({
            vid: item.variableValue,
            name: item.nodeValue,
            value: 0
          });
        });
      }
    }


    //更新数据
    const refreshDynamicData = () => {
      //更新动态数据
      if ((dynamicData.value) && (dynamicData.value.length > 0)) {
        dynamicData.value.forEach((el, index) => {
          if (xyData.value[index].vid === el.varId) {
            xyData.value[index].value = el.vData;
          }
        });
      }

      //更新数据集
      for (let i = 0; i < xyData.value.length; i++) {
        //丢掉第一个元素,确保保持固定长度
        if (xyDataSet.value[i]) {
          if (xyDataSet.value[i].length >= xScale.value.length) {
            xyDataSet.value[i].shift();
          }

          //插入1个新元素
          xyDataSet.value[i].push(xyData.value[i]);
        } else {
          let arr: CDynamicDataItem[] = [];
          arr.push(xyData.value[i]);
          xyDataSet.value.push(arr);
        }
      }
    }

    //初始化
    const init = () => {
      configProperty();
      refreshDynamicData();
      addToChart();

      if (myRef.value) {
        myRef.value.updateView();
        myRef.value.onResize();
      }
    }

    // watch dom尺寸变化,调整子控件大小
    watch(() => detail, () => {
      init();
    }, { deep: true });

    //监视变量变化
    watch(() => dynamicData, () => {
      refreshDynamicData();
    }, { deep: true })

    //挂载组件
    onMounted(() => {
      init();
    });

    return {
      myRef,
      detail,
      myOption
    };
  }
});
</script>

<style lang="scss" scoped>
.chart-container {
  position: absolute;
  left: 0px;
  top: 0px;
  width: 100%;
  height: 100%;
  text-align: center;
}
</style>
